//
// Created by luosong on 15/8/24.
// Copyright (c) 2015 CHANJET. All rights reserved.
//

#import "CSPNetworking.h"
#import "CSPTask.h"
#import "CSPNetworkingRequest.h"
#import "CSPTaskCompletionSource.h"
#import "CSPURLSessionManager.h"

NSString *const CSPNetworkingErrorDomain = @"com.chanjet.CSPNetworkingErrorDomain";
NSString *const CSPGeneralErrorDomain = @"com.chanjet.CSPGeneralErrorDomain";

#pragma mark - CSPHTTPMethod

@implementation NSString (CSPHTTPMethod)

+ (instancetype)csp_stringWithHTTPMethod:(CSPHTTPMethod)HTTPMethod {
    NSString *string = nil;
    switch (HTTPMethod) {
        case CSPHTTPMethodGET:
            string = @"GET";
            break;
        case CSPHTTPMethodHEAD:
            string = @"HEAD";
            break;
        case CSPHTTPMethodPOST:
            string = @"POST";
            break;
        case CSPHTTPMethodPUT:
            string = @"PUT";
            break;
        case CSPHTTPMethodPATCH:
            string = @"PATCH";
            break;
        case CSPHTTPMethodDELETE:
            string = @"DELETE";
            break;

        default:
            break;
    }

    return string;
}

@end

#pragma mark - CSPNetworking

@interface CSPNetworking()

@property (nonatomic, strong) CSPURLSessionManager *networkManager;

@end

@implementation CSPNetworking

- (instancetype)initWithConfiguration:(CSPRequestConfig *)configuration {
    if (self = [super init]) {
        _networkManager = [[CSPURLSessionManager alloc] initWithConfiguration:configuration];
    }

    return self;
}

- (CSPTask *)sendRequest:(CSPNetworkingRequest *)request {
    NSParameterAssert(request != nil);

    CSPTaskCompletionSource *taskCompletionSource = [CSPTaskCompletionSource taskCompletionSource];

    [self.networkManager dataTaskWithRequest:request completionHandler:^(id responseObject, NSError *error) {
        if (!error) {
            [taskCompletionSource setResult:responseObject];
        }
        else {
            [taskCompletionSource setError:error];
        }
    }];

    return taskCompletionSource.task;
}

@end

@interface CSPRequest()

@property (nonatomic, strong) CSPNetworkingRequest *internalRequest;
@property (nonatomic, assign) NSNumber *shouldWriteDirectly;

@end

@implementation CSPRequest

- (instancetype)init {
    if (self = [super init]) {
        _internalRequest = [CSPNetworkingRequest new];
    }

    return self;
}

- (BOOL)isCancelled {
    return [self.internalRequest isCancelled];
}

- (CSPTask *)cancel {
    [self.internalRequest cancel];
    return [CSPTask taskWithResult:nil];
}

- (CSPTask *)pause {
    [self.internalRequest pause];
    return [CSPTask taskWithResult:nil];
}

- (NSDictionary *)dictionaryValue {
    NSDictionary *dictionaryValue = [super dictionaryValue];
    NSMutableDictionary *mutableDictionaryValue = [dictionaryValue mutableCopy];

    [dictionaryValue enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        if ([key isEqualToString:@"internalRequest"]) {
            [mutableDictionaryValue removeObjectForKey:key];
        }
    }];

    return mutableDictionaryValue;
}

@end